package org.wattdepot.cli.command;

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import org.wattdepot.client.BadXmlException;
import org.wattdepot.client.MiscClientException;
import org.wattdepot.client.NotAuthorizedException;
import org.wattdepot.client.ResourceNotFoundException;
import org.wattdepot.client.WattDepotClient;
import org.wattdepot.resource.property.jaxb.Property;
import org.wattdepot.resource.sensordata.jaxb.SensorData;
import javax.xml.datatype.XMLGregorianCalendar;
import org.wattdepot.util.tstamp.Tstamp;

/**
 * Implements the DailySensorDataCommand handler.
 * 
 * @author Yichi Xu
 *
 */
public class DailySensorDataCommand extends WattDepotCliCommand {
  /**
   * Creates an instance of the DailySensorData command handler.
   * 
   * @param client An instance of the WattDepotClient.
   */
  public DailySensorDataCommand(WattDepotClient client) {
    super(client);
  }
  
  /**
   * List sensor data for a specific day.
   * @see org.wattdepot.cli.command.WattDepotCliCommand#doCommand(String)
   * 
   * @param command The command to process.
   * @return The result of the command.
   */
  @Override
  public String doCommand(String command) {
    StringTokenizer tokenizer = new StringTokenizer(command);
    List<String> tokens = new ArrayList<String>();
    XMLGregorianCalendar startTime = null;

    while (tokenizer.hasMoreTokens()) {
      tokens.add(tokenizer.nextToken());
    }
    
    if (tokens.size() != 4) {
      return this.reportError(PARAMETER_COUNT_ERROR);
    }
    
    if (!"dailysensordata".equals(tokens.get(0))) {
      return WattDepotCliCommand.reportUnknownCommand(command);
    }
    
    if (!"day".equals(tokens.get(2))) {
      return this.reportError(PARAMETER_ERROR + tokens.get(2));
    }
    
    try {
      startTime = Tstamp.makeTimestamp(tokens.get(3));
    }
    catch (Exception ex) {
      return this.reportError(TSTAMP_ERROR + tokens.get(3));
    }
    try {
      return this.listSensorDataDay(tokens.get(1), startTime);
    }
    catch (ResourceNotFoundException ex) {
      return this.reportError(WattDepotCliCommand.SOURCE_ERROR + tokens.get(1));
    }
    catch (BadXmlException ex) {
      return this.reportError(WattDepotCliCommand.BAD_XML_ERROR);
    }
    catch (Exception ex) {
      return this.reportError(WattDepotCliCommand.CONNECTION_ERROR);
    }
  }
  
  /**
   * List sensor data for a specific day.
   * @param sourceName the name of the source
   * @param startTime the starting time of the day
   * @return the message contains information of all the sensor data in that day 
   * @throws MiscClientException Exception
   * @throws BadXmlException Exception
   * @throws ResourceNotFoundException Exception
   * @throws NotAuthorizedException Exception
   */
  String listSensorDataDay(String sourceName, XMLGregorianCalendar startTime) 
  throws NotAuthorizedException, ResourceNotFoundException, BadXmlException, MiscClientException {
    StringBuffer buf = new StringBuffer(255);
    String format = "%1$s  %2$s: %3$s  %4$s: %5$s \n";
    XMLGregorianCalendar endTime = Tstamp.incrementDays(startTime, 1);
    List<SensorData> sensorDataList = client.getSensorDatas(sourceName, startTime, endTime);
    String timestamp;
    String tool;
    String propertyString;
    Double power;
    for (SensorData sensorData : sensorDataList) {
      timestamp = sensorData.getTimestamp().toString();
      tool = sensorData.getTool();
      StringBuffer propertyBuf = new StringBuffer();
      
      for (Property property : sensorData.getProperties().getProperty()) {
        propertyBuf.append('(');
        propertyBuf.append(property.getKey());
        propertyBuf.append(" : ");
        //convert to megawatts
        power = Double.parseDouble(property.getValue());
        //power = power / 1000000.00;
        //propertyBuf.append(String.format("%.2f", String.valueOf(power)));
        propertyBuf.append(power);
        propertyBuf.append("), ");
      }
      
      propertyString = propertyBuf.toString();
      propertyString = propertyString.substring(0, propertyString.length() - 2);
      buf.append(String.format(format, timestamp, "Tool", tool, "Properties", propertyString));
    }
    
    buf.append("Total ");
    buf.append(sensorDataList.size());
    buf.append(" records.\n");
    return buf.toString();
  }

  /**
   * Gets the help string associated with the DailySensorData command.
   * 
   * @see org.wattdepot.cli.command.WattDepotCliCommand#getHelp()
   * @return Information on how to invoke the list sensor data day command.
   */
  @Override
  public String getHelp() {
    return "dailysensordata {source} day {day}\n"
      + "  Prints a table listing all of the sensor data instances for the specified day.\n";
  }
}
